using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Utilities.Menu.UIElements;
using Services;
using SpaceBattle.Logic.SampleLevel;
using SpaceBattle;
using System.IO.IsolatedStorage;
using System.IO;
using SpaceBattle.Resources;
using Utilities;
using System.Threading;

namespace SpaceBattle.Menu
{
  public class MainMenu : DrawableGameComponent
  {

    enum MenuState
    {
      MainMenu,
      Credits,
      Controls,
      HighScores,
      ModeSelection,
      CampaignOption
    }

    SpriteBatch sprite_batch;
    InputManager input_manager;

    Matrix screen_transform;
    Box box;
    Texture2D bg;
    float alpha = 1.0f, wait_time_to_tap = 0.5f;
    bool increaseAlpha = true, campaign_completed = false;
    MenuState menu_state = MenuState.MainMenu, next_state;

    public MainMenu(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      input_manager = new InputManager(game);
      game.Components.Add(input_manager);

      var cs = Leaderboard.GetCampaignState().CampaignState;
      if (cs.LevelPlayed == CampaignMode.NUMBER_OF_LEVELS || cs.LevelPlayed == 0)
        campaign_completed = true;

      this.UpdateOrder = (int)ComponentOrders.TRANSITION + 1;
      this.DrawOrder = (int)ComponentOrders.UI;
    }

    public override void Initialize()
    {
      sprite_batch = Services.GetService(typeof(SpriteBatch)) as SpriteBatch;

      var input_service = Services.GetService(typeof(IInputManager)) as IInputManager;
      input_service.OnTap += on_tap;

      base.Initialize();
    }

    Thread t;
    protected override void LoadContent()
    {
      screen_transform = Matrix.CreateScale(GraphicsDevice.Viewport.Width / SpaceBattleGame.DEFAULT_SCR_WIDTH,
          GraphicsDevice.Viewport.Height / SpaceBattleGame.DEFAULT_SCR_HEIGHT, 1.0f);
      double_tap = Content.Load<Texture2D>("Menu/double_tap");
      single_tap = Content.Load<Texture2D>("Menu/single_tap");
      long_tap = Content.Load<Texture2D>("Menu/long_tap");
      team_logo = Content.Load<Texture2D>("Menu/vst_logo");
      game_title = Content.Load<Texture2D>("Menu/g_title");
      font_32 = Content.Load<SpriteFont>("Fonts/OCRAExtended30");
      font_16 = Content.Load<SpriteFont>("Fonts/OCRAExtended16");
      font_18 = Content.Load<SpriteFont>("Fonts/OCRAExtended18");
      click = Content.Load<SoundEffect>("Audio/button").CreateInstance();
      error = Content.Load<SoundEffect>("Audio/error").CreateInstance();

      click.Volume = AudioManager.Volume; click.Pan = 0.0f; click.Pitch = 0.0f;
      error.Volume = AudioManager.Volume; error.Pan = 0.0f; error.Pitch = 0.0f;

      box = new Box(new Texture2D[] { Game.Content.Load<Texture2D>("UI/pause_menu_border"),
            Game.Content.Load<Texture2D>("UI/WhitePixel"), Game.Content.Load<Texture2D>("UI/pause_menu_border") },
          new Vector2(445, 70), new Vector2(320, 380), Color.Black, 0.8f);

      buttons = CreateRightAlignedButtons(new string[] { Strings.MainMenu_Play, Strings.MainMenu_HighScores, Strings.MainMenu_Controls, 
                Strings.MainMenu_Credits, Strings.MainMenu_Exit }, 20, 100, 10, 30 + game_title.Width);

      mode_buttons = CreateRightAlignedButtons(new string[] { Strings.Mode3, /*Strings.Mode2,*/ Strings.Mode1, Strings.Back },
          25, 220, 10, 30 + game_title.Width);
      back = CreateButtons(new string[] { Strings.Back }, 0, 420, 10)[0];
      resume = CreateRightAlignedButtons(new string[] { Strings.ContinueCamp }, 0, 210, 10, 30 + game_title.Width)[0];
      new_campaign = CreateRightAlignedButtons(new string[] { Strings.NewCampaing }, 0, 300, 10, 30 + game_title.Width)[0];
      co_back = CreateRightAlignedButtons(new string[] { Strings.Back }, 0, 390, 10, 30 + game_title.Width)[0];

      t = new Thread(() =>
      {
        // Ship Selection
        Content.Load<Texture2D>("Menu/title_bg");
        Content.Load<Texture2D>("Menu/stat_bg");
        Content.Load<Texture2D>("Menu/buy_box");
        Content.Load<SpriteFont>("Fonts/OCRAExtended32");
        Content.Load<SpriteFont>("Fonts/OCRAExtended18");
        Content.Load<SpriteFont>("Fonts/Orator14");
        Content.Load<SpriteFont>("Fonts/VerySmall");
        Content.Load<Texture2D>("UI/WhitePixel");
        Content.Load<SoundEffect>("Audio/error");

        // Various Model
        var c = ConfigurationService.GetDefaulConfiguration();

        for (int i = 0; i < c.Ships.Count; i++)
          Content.Load<Model>(c.Ships[i].ModelPath);
      });

      t.Start();

      var sc = Leaderboard.GetScores();

      for (int k = 0; k < sc.Count; k++)
        scores.Add(sc[k]);

      scores = scores.OrderByDescending(s => s.Score).ToList();

      base.LoadContent();
    }

    protected override void Dispose(bool disposing)
    {
      Services.RemoveService(typeof(IInputManager));

      base.Dispose(disposing);
    }

    public override void Update(GameTime gameTime)
    {
      float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

      wait_time_to_tap -= dt;

      if (input_manager.IsBackButtonPressed() && menu_state == MenuState.MainMenu)
        StateManager.ExitGame(Game);

      if (increaseAlpha)
      {
        if (!box.InTransition)
          alpha = MathHelper.Clamp(alpha + dt * 2.0f, 0, 1);
      }
      else
      {
        alpha = MathHelper.Clamp(alpha - dt * 2.0f, 0, 1);
        if (alpha == 0.0f)
        {
          increaseAlpha = true;
          menu_state = next_state;
        }
      }

      if (increaseAlpha) box.Update(dt * 2.0f);

      base.Update(gameTime);
    }

    #region Update Helper

    void OnMainMenuButtonPressed(int tapped_button)
    {
      switch (tapped_button)
      {
        case 0:
          box.StartTransition(new Vector2(445, 190), new Vector2(320, 260));
          StartTransition(MenuState.ModeSelection);
          break;
        case 1:
          box.StartTransition(new Vector2(195, 25), new Vector2(410, 380));
          StartTransition(MenuState.HighScores);     
          break;
        case 2:
          //box.StartTransition(new Vector2(45, 40), new Vector2(710, 360));
          //StartTransition(MenuState.Controls);
          input_manager.OnTap -= on_tap;
          this.Enabled = false;
          this.Visible = false;
          StateManager.selectControlsScreenFromMainMenu(Game);
          //var slide = new SlideScreen(Game);
          //Components.Add(slide);
          //slide.Disposed += new EventHandler<EventArgs>(
          //    (sender, e) => {                  
          //        this.Enabled = true;
          //        this.Visible = true;
          //        input_manager.OnTap += on_tap;
          //    });
          break;
        case 3:
          box.StartTransition(new Vector2(120, 70), new Vector2(560, 345));
          StartTransition(MenuState.Credits);
          break;
        case 4:
          StateManager.ExitGame(Game);
          break;
        default:
          break;
      }
    }

    private void MainMenuUpdate(int tap_x, int tap_y)
    {
      var tapped_button = -1;

      for (int i = 0; i < buttons.Count(); i++)
        if (buttons[i].CollisionBox.Contains(tap_x, tap_y))
        {
          tapped_button = i;
          if (!(click.State == SoundState.Playing)) click.Play();
          break;
        }

      OnMainMenuButtonPressed(tapped_button);
    }

    void OnModeSelectionButtonPressed(int tapped_button)
    {
      if (input_manager.IsBackButtonPressed()) tapped_button = 2;

      switch (tapped_button)
      {
        case 0:
          if (!Game.IsTrial())
          {
            if (!(click.State == SoundState.Playing)) click.Play();
            if (!campaign_completed)
              box.StartTransition(new Vector2(450, 170), new Vector2(300, 290));
            else
              box.StartTransition(new Vector2(450, 270), new Vector2(300, 190));
            ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
            StartTransition(MenuState.CampaignOption);
          }
          else
            error.Play();
          break;
        //case 1:
        //    click.Play(AudioManager.Volume, 0.0f, 0.0f);
        //    ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
        //    StateManager.SelectSkirmishOptionScreen(Game);
        //    break;
        //case 2:
        case 1:
          if (!(click.State == SoundState.Playing)) click.Play();
          ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
          StateManager.SelectSurvivalLevel(Game, t, GameMode.Survival);
          break;
        //case 3:
        case 2:
          if (!(click.State == SoundState.Playing)) click.Play();
          box.StartTransition(new Vector2(445, 70), new Vector2(320, 380));
          StartTransition(MenuState.MainMenu);
          break;
        default:
          break;
      }
    }

    private void ModeSelectionUpdate(int tap_x, int tap_y)
    {
      var tapped_button = -1;

      for (int i = 0; i < mode_buttons.Count(); i++)
        if (mode_buttons[i].CollisionBox.Contains(tap_x, tap_y))
        {
          tapped_button = i;
          //if (!(click.State == SoundState.Playing)) click.Play();
          break;
        }

      OnModeSelectionButtonPressed(tapped_button);
    }

    #endregion

    public override void Draw(GameTime gameTime)
    {
      sprite_batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screen_transform);

      //sprite_batch.Draw(bg, new Rectangle(0, 0, 480, 800), Color.White);

      sprite_batch.Draw(game_title, new Vector2(30, 100),
          Color.White);

      box.Draw(sprite_batch);

      switch (menu_state)
      {
        case MenuState.MainMenu:
          DrawMenu();
          break;
        case MenuState.Credits:
          DrawCredits();
          break;
        case MenuState.Controls:
          DrawControls();
          break;
        case MenuState.HighScores:
          DrawHighScores();
          break;
        case MenuState.ModeSelection:
          DrawSelectMode();
          break;
        case MenuState.CampaignOption:
          DrawCampaignOption();
          break;
      }

      sprite_batch.End();

      base.Draw(gameTime);
    }

    #region Private Methods

    #region OnTap & CreateButtons

    Button back, resume, new_campaign;
    SoundEffectInstance click;
    private void on_tap(Vector2 tap_position)
    {
      if (wait_time_to_tap <= 0.0f)
      {
        int tap_x = (int)(tap_position.X / screen_transform.M11), tap_y = (int)(tap_position.Y / screen_transform.M22);

        switch (menu_state)
        {
          case MenuState.MainMenu:
            MainMenuUpdate(tap_x, tap_y);
            break;
          case MenuState.ModeSelection:
            ModeSelectionUpdate(tap_x, tap_y);
            break;
          case MenuState.CampaignOption:
            if (resume.CollisionBox.Contains(tap_x, tap_y) && !campaign_completed)
            {
              if (!(click.State == SoundState.Playing)) click.Play();
              StateManager.SelectCampaignScreen(Game, t);
            }
            else if (new_campaign.CollisionBox.Contains(tap_x, tap_y))
            {
              if (!(click.State == SoundState.Playing)) click.Play();
              Leaderboard.ResetCampaignState(false);
              ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
              StateManager.SelectCampaignScreen(Game, t);
            }
            else if (co_back.CollisionBox.Contains(tap_x, tap_y) || input_manager.IsBackButtonPressed())
            {
              if (!(click.State == SoundState.Playing)) click.Play();
              box.StartTransition(new Vector2(445, 190), new Vector2(320, 260));
              StartTransition(MenuState.ModeSelection);
            }
            break;
          default:
            if (back.CollisionBox.Contains(tap_x, tap_y) || input_manager.IsBackButtonPressed())
            {
              if (!(click.State == SoundState.Playing)) click.Play();
              box.StartTransition(new Vector2(445, 70), new Vector2(320, 380));
              StartTransition(MenuState.MainMenu);
            }
            break;
        }
      }
    }

    private Button[] CreateButtons(string[] labels, int offset, int starting_y, int padding)
    {
      int w = GraphicsDevice.Viewport.Width;
      int h = GraphicsDevice.Viewport.Height;
      Button[] bs = new Button[labels.Count()];

      for (int i = 0; i < bs.Count(); i++)
      {
        Vector2 label_measure = font_32.MeasureString(labels[i]);
        int x = (int)(w / 2 - label_measure.X / 2.0f);
        int y = starting_y + i * (offset + (int)label_measure.Y);
        bs[i] = new Button()
        {
          CollisionBox = new Rectangle(x - padding, y - padding, (int)label_measure.X + padding * 2, (int)label_measure.Y + padding * 2),
          Label = labels[i],
          Position = new Vector2(x, y)
        };
      }

      return bs;
    }

    private enum ButtonAligment
    {
      Left,
      Right
    }

    private Button[] CreateRightAlignedButtons(string[] labels, int offset, int starting_y, int padding, int align_val)
    {
      int w = GraphicsDevice.Viewport.Width;
      int h = GraphicsDevice.Viewport.Height;
      Button[] bs = new Button[labels.Count()];

      for (int i = 0; i < bs.Count(); i++)
      {
        Vector2 label_measure = font_32.MeasureString(labels[i]);
        int x = (int)((w + align_val) / 2.0f - label_measure.X / 2.0f);
        int y = starting_y + i * (offset + (int)label_measure.Y);
        bs[i] = new Button()
        {
          CollisionBox = new Rectangle(x - padding, y - padding, (int)label_measure.X + padding * 2, (int)label_measure.Y + padding * 2),
          Label = labels[i],
          Position = new Vector2(x, y)
        };
      }

      return bs;
    }

    #endregion

    private void StartTransition(MenuState next)
    {
      next_state = next;
      increaseAlpha = false;
    }

    #region Draw Helper

    #region HighScores

    List<LeaderboardEntry> scores = new List<LeaderboardEntry>();
    private void DrawHighScores()
    {
      var title = Strings.MainMenu_HighScores;
      sprite_batch.DrawString(font_32, title, new Vector2(GraphicsDevice.Viewport.Width / 2.0f - font_32.MeasureString(title).X / 2.0f,
          40) + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, title, new Vector2(GraphicsDevice.Viewport.Width / 2.0f - font_32.MeasureString(title).X / 2.0f,
          40), Color.White * alpha);

      int i = 0;

      for (int y = 0; y < scores.Count; y++)
      {
        var s = scores[y];
        sprite_batch.DrawString(font_16, s.Name, new Vector2(250, 130 + 40 * i), Color.White * alpha);
        sprite_batch.DrawString(font_16, s.Score.ToString(), new Vector2(370, 130 + 40 * i), Color.White * alpha);
        sprite_batch.DrawString(font_16, s.Date, new Vector2(450, 130 + 40 * i), Color.White * alpha);
        i++;
      }

      if (i == 0)
      {
        sprite_batch.DrawString(font_16, "--", new Vector2(Game.GraphicsDevice.Viewport.Width / 2 - 10.0f, 150), Color.White * alpha);
      }

      sprite_batch.DrawString(font_32, back.Label, back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, back.Label, back.Position, Color.White * alpha);
    }

    #endregion

    #region Credits
    Texture2D single_tap, double_tap, long_tap, team_logo;
    private void DrawCredits()
    {
      sprite_batch.Draw(team_logo, new Rectangle(155, (int)(GraphicsDevice.Viewport.Height / 2.0f - 39), 200, 78),
          Color.White * alpha);

      //sprite_batch.DrawString(font_16, "Lead Developer:", new Vector2(120, 380), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Giuseppe Maggiore", new Vector2(390, 110), Color.White * alpha);
      //sprite_batch.DrawString(font_16, "Game Designer:", new Vector2(120, 480), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Andrea Gasparetto", new Vector2(390, 155), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Francesco Usai", new Vector2(390, 200), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Francesco Boscariol", new Vector2(390, 245), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Luca Cosmo", new Vector2(390, 290), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Davide Luzzu", new Vector2(390, 335), Color.White * alpha);

      sprite_batch.DrawString(font_32, back.Label, back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, back.Label, back.Position, Color.White * alpha);
    }

    #endregion

    #region Controls

    private void DrawControls()
    {
      sprite_batch.DrawString(font_16, Strings.Controls_SingleTap + "\n" + Strings.Controls_ST_Desc_OF.Replace("\\n", "\n") +
          "\n" + Strings.Controls_ST_Desc_OE.Replace("\\n", "\n") + "\n" +
          Strings.Controls_ST_Desc_OS.Replace("\\n", "\n"), new Vector2(61, 91), Color.DarkGray * alpha); // 150
      sprite_batch.DrawString(font_16, Strings.Controls_SingleTap + "\n" + Strings.Controls_ST_Desc_OF.Replace("\\n", "\n") +
          "\n" + Strings.Controls_ST_Desc_OE.Replace("\\n", "\n") + "\n" +
          Strings.Controls_ST_Desc_OS.Replace("\\n", "\n"), new Vector2(60, 90), Color.White * alpha); // 150

      //sprite_batch.Draw(double_tap, new Vector2(85, 360), Color.White * alpha);
      sprite_batch.DrawString(font_16, Strings.Controls_DoubleTap + "\n" + Strings.Controls_DT_Desc_OE.Replace("\\n", "\n"),
          new Vector2(421, 91), Color.DarkGray * alpha);
      sprite_batch.DrawString(font_16, Strings.Controls_DoubleTap + "\n" + Strings.Controls_DT_Desc_OE.Replace("\\n", "\n"),
          new Vector2(420, 90), Color.White * alpha);

      //sprite_batch.Draw(long_tap, new Vector2(85, 530), Color.White * alpha);
      sprite_batch.DrawString(font_16, Strings.Controls_LongTap + "\n" + Strings.Controls_LT_Desc_OF.Replace("\\n", "\n"),
          new Vector2(421, 281), Color.DarkGray * alpha);
      sprite_batch.DrawString(font_16, Strings.Controls_LongTap + "\n" + Strings.Controls_LT_Desc_OF.Replace("\\n", "\n"),
          new Vector2(420, 280), Color.White * alpha);

      sprite_batch.DrawString(font_16, Strings.Pinch.Replace("\\n", "\n"), new Vector2(421, 211), Color.DarkGray * alpha);
      sprite_batch.DrawString(font_16, Strings.Pinch.Replace("\\n", "\n"), new Vector2(420, 210), Color.White * alpha);

      //sprite_batch.Draw(single_tap, new Vector2(85, 100), Color.White * alpha);
      //sprite_batch.DrawString(font_32, Strings.Controls_SingleTap, new Vector2(150, 120), Color.White * alpha);
      //sprite_batch.DrawString(font_16, Strings.Controls_ST_Desc_OF.Replace("\\n", "\n"), new Vector2(80, 180), Color.White * alpha);
      //sprite_batch.DrawString(font_16, Strings.Controls_ST_Desc_OE.Replace("\\n", "\n"), new Vector2(80, 260), Color.White * alpha);

      //sprite_batch.Draw(double_tap, new Vector2(85, 360), Color.White * alpha);
      //sprite_batch.DrawString(font_32, Strings.Controls_DoubleTap, new Vector2(150, 370), Color.White * alpha);
      //sprite_batch.DrawString(font_16, Strings.Controls_DT_Desc_OE.Replace("\\n", "\n"), new Vector2(80, 430), Color.White * alpha);

      //sprite_batch.Draw(long_tap, new Vector2(85, 530), Color.White * alpha);
      //sprite_batch.DrawString(font_32, Strings.Controls_LongTap, new Vector2(150, 540), Color.White * alpha);
      //sprite_batch.DrawString(font_16, Strings.Controls_LT_Desc_OF.Replace("\\n", "\n"), new Vector2(80, 600), Color.White * alpha);

      //sprite_batch.DrawString(font_32, back.Label, back.Position + Vector2.One * 2.5f, Color.SteelBlue * alpha);
      //sprite_batch.DrawString(font_32, back.Label, back.Position, Color.White * alpha);

      //sprite_batch.DrawString(font_16, Strings.Controls_SingleTap + "\n" + Strings.Controls_ST_Desc_OF.Replace("\\n", "\n") +
      //    "\n" + Strings.Controls_ST_Desc_OE.Replace("\\n", "\n") + "\n" +
      //    Strings.Controls_ST_Desc_OS.Replace("\\n", "\n"), new Vector2(81, 101), Color.Black * alpha);
      //sprite_batch.DrawString(font_16, Strings.Controls_SingleTap + "\n" + Strings.Controls_ST_Desc_OF.Replace("\\n", "\n") + 
      //    "\n" + Strings.Controls_ST_Desc_OE.Replace("\\n", "\n") + "\n" +
      //    Strings.Controls_ST_Desc_OS.Replace("\\n", "\n"), new Vector2(80, 100), Color.White * alpha);

      //sprite_batch.DrawString(font_16, Strings.Controls_DoubleTap + "\n" + Strings.Controls_DT_Desc_OE.Replace("\\n", "\n"),
      //    new Vector2(81, 371), Color.Black * alpha);
      //sprite_batch.DrawString(font_16, Strings.Controls_DoubleTap + "\n" + Strings.Controls_DT_Desc_OE.Replace("\\n", "\n"),
      //    new Vector2(80, 370), Color.White * alpha);

      //sprite_batch.DrawString(font_16, Strings.Controls_LongTap + "\n" + Strings.Controls_LT_Desc_OF.Replace("\\n", "\n"),
      //    new Vector2(81, 491), Color.Black * alpha);
      //sprite_batch.DrawString(font_16, Strings.Controls_LongTap + "\n" + Strings.Controls_LT_Desc_OF.Replace("\\n", "\n"),
      //    new Vector2(80, 490), Color.White * alpha);

      //sprite_batch.DrawString(font_16, Strings.Pinch.Replace("\\n", "\n"), new Vector2(81, 581), Color.Black * alpha);
      //sprite_batch.DrawString(font_16, Strings.Pinch.Replace("\\n", "\n"), new Vector2(80, 580), Color.White * alpha);

      sprite_batch.DrawString(font_32, back.Label, back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, back.Label, back.Position, Color.White * alpha);
    }

    #endregion

    #region Menu

    Button[] buttons;
    SpriteFont font_32, font_16;
    Texture2D game_title;

    void DrawMenu()
    {

      for (int i = 0; i < buttons.Count(); i++)
      {
        sprite_batch.DrawString(font_32, buttons[i].Label, buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
        sprite_batch.DrawString(font_32, buttons[i].Label, buttons[i].Position, Color.White * alpha);
      }

    }

    #endregion

    #region SelectGameMode

    Button[] mode_buttons;
    private SoundEffectInstance error;
    private SpriteFont font_18;
    private Button co_back;

    void DrawSelectMode()
    {
      var a = 1.0f;
      for (int i = 0; i < mode_buttons.Count(); i++)
      {
        if (i == 0 && Game.IsTrial())
            a = 0.5f;
        else
            a = 1.0f;

        sprite_batch.DrawString(font_32, mode_buttons[i].Label, mode_buttons[i].Position + Vector2.One * 2.5f, Color.Black * (Math.Min(alpha, a)));
        sprite_batch.DrawString(font_32, mode_buttons[i].Label, mode_buttons[i].Position, Color.White * (Math.Min(alpha, a)));
      }

    }

    void DrawCampaignOption()
    {
      if (!campaign_completed)
      {
        sprite_batch.DrawString(font_32, resume.Label, resume.Position + Vector2.One * 2.5f, Color.Black * alpha);
        sprite_batch.DrawString(font_32, resume.Label, resume.Position, Color.White * alpha);
      }

      sprite_batch.DrawString(font_32, new_campaign.Label, new_campaign.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, new_campaign.Label, new_campaign.Position, Color.White * alpha);

      sprite_batch.DrawString(font_32, co_back.Label, co_back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, co_back.Label, co_back.Position, Color.White * alpha);
    }

    #endregion

    #endregion

    #endregion

    ContentManager Content { get { return Game.Content; } }
    GameServiceContainer Services { get { return Game.Services; } }
    GameComponentCollection Components { get { return Game.Components; } }
  }
}
